import 'dart:io';

import 'package:aero_frisbee/app/conf/local_resource.dart';
import 'package:aero_frisbee/app/model/af_block_list_model/af_block_list_model.dart';
import 'package:aero_frisbee/app/model/af_coin_create_model/af_coin_create_model.dart';
import 'package:aero_frisbee/app/model/af_coin_product_model/af_coin_product_model.dart';
import 'package:aero_frisbee/app/model/af_friend_info_model/af_friend_info_model.dart';
import 'package:aero_frisbee/app/model/af_home_user_model/af_home_user_model.dart';
import 'package:aero_frisbee/app/model/af_oss_policy_model/af_oss_policy_model.dart';
import 'package:aero_frisbee/app/model/af_short_link_model/af_short_link_model.dart';
import 'package:aero_frisbee/app/model/af_strategy_model/af_strategy_model.dart';
import 'package:aero_frisbee/app/model/af_user_info_model/af_user_info_model.dart';
import 'package:aero_frisbee/app/model/login_respose_model/login_respose_model.dart';
import 'package:aero_frisbee/app/state/easy_refresh_state.dart';
import 'package:aero_frisbee/app/store/app_store.dart';
import 'package:aero_frisbee/core/http/af_http_util.dart';
import 'package:aero_frisbee/pages/modues/message/pages/followed/view_model/af_followed_list_state.dart';
import 'package:dio/dio.dart';
import 'package:get_it/get_it.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:tuple/tuple.dart';

import 'af_global_url.dart';

part 'af_req_api.g.dart';

@Riverpod(keepAlive: true)
AfReqApi appApi(AppApiRef ref) {
  return AfReqApi(ref);
}

class AfReqApi {
  final ProviderRef ref;
  AfReqApi(this.ref);

  Future<Tuple2<String, dynamic>> getAppConfig() async {
    final ret = await AfHttpUtil.I.getParse(AfGlobalUrl.getAppConfig, params: {
      "ver": 0,
    }, parseJsonFn: ((data) {
      return Tuple2(data['ver'] as String, data['items']);
    }));

    return ret;
  }

  Future<LoginResposeModel> launchByLoginRespose(
      LoginResposeModel respose) async {
    var retModel = respose;
    final strategyItem = await getStrategy();
    retModel = retModel.copyWith(
        userServiceAccountId: strategyItem.userServiceAccountId);
    final appCof = await getAppConfig();
    retModel = retModel.copyWith(ver: appCof.item1);
    for (var item in appCof.item2) {
      if (item['name'] == 'google_translation_key') {
        retModel = retModel.copyWith(googleTranslationKey: item['data']);
      }
      if (item['name'] == 'rck') {
        retModel = retModel.copyWith(rck: item['data']);
      }
    }
    final tongcloudToken = await getRongcloudToken();
    retModel = retModel.copyWith(tongcloudToken: tongcloudToken);
    return retModel;
  }

  Future<LoginResposeModel> oauthLogin({
    int oauthType = 4,
    required String token,
  }) async {
    final ret = await AfHttpUtil.I.postParse(
      AfGlobalUrl.oauth,
      queryParameters: {
        "oauthType": oauthType,
        "token": token,
      },
      parseJsonFn: ((data) => LoginResposeModel.fromJson(data)),
    );

    ///登录成功及时更新token
    GetIt.I.get<AppStore>().token = ret.token ?? '';
    GetIt.I.get<AppStore>().userInfo = ret.userInfoModel;
    final retModel = await launchByLoginRespose(ret);
    return retModel;
  }

  Future<bool> isValidToken({
    required String token,
  }) async {
    final ret = await AfHttpUtil.I.postParse(
      AfGlobalUrl.validTokenApi,
      params: {'token': token},
      parseJsonFn: ((data) => data),
    );

    return ret;
  }

  Future<AfStrategyModel> getStrategy() async {
    final ret = await AfHttpUtil.I.getParse(
      AfGlobalUrl.getStrategy,
      parseJsonFn: ((data) => AfStrategyModel.fromJson(data)),
    );
    return ret;
  }

  Future<AfUserInfoModel> fetchUserInfo({required String userId}) async {
    final ret = await AfHttpUtil.I.getParse(
      AfGlobalUrl.fetchUserInfoApi,
      params: {"userId": userId},
      parseJsonFn: ((data) => AfUserInfoModel.fromJson(data)),
    );
    return ret;
  }

  Future<String> getRongcloudToken() async {
    final ret = await AfHttpUtil.I.getParse(
      AfGlobalUrl.rongCloudTokenApi,
      parseJsonFn: ((data) => data),
    );
    return ret;
  }

  Future<List<AfHomeUserModel>> fetchBroadcaster() async {
    final ret = await AfHttpUtil.I.postParse(
      AfGlobalUrl.fetchBroadcasterApi,
      params: {
        "category": "Popular", // 分类固定传Popular
        "isPageMode": true,
        "isRemoteImageUrl": true, // 必须为true 否则返回的头像链接需要拼接
        "limit": 20,
        "page": 1,
        "tag": "All",
      },
      parseJsonFn: ((data) => List<AfHomeUserModel>.from(
          data.map((x) => AfHomeUserModel.fromJson(x)))),
    );

    return ret;
  }

  Future<List<AfShortLinkModel>> shortLink() async {
    final ret = await AfHttpUtil.I.postParse(
      AfGlobalUrl.shortLink,
      params: videoParamStr,
      parseJsonFn: ((data) => List<AfShortLinkModel>.from(
          data.map((x) => AfShortLinkModel.fromJson(x)))),
    );

    final titleLis = LocalResource.videoList;
    for (var i = 0; i < ret.length; i++) {
      if (titleLis.length > i) {
        ret[i] = ret[i].copyWith(title: titleLis[i]);
      }
    }
    return ret;
  }

  Future<List<AfCoinProductModel>> getAfCoinProductList() async {
    final ret = await AfHttpUtil.I.postParse(
      AfGlobalUrl.productListApi,
      params: {
        "isIncludeSubscription": false,
        "payChannel": "IAP",
      },
      parseJsonFn: ((data) => List<AfCoinProductModel>.from(
          data.map((x) => AfCoinProductModel.fromJson(x)))),
    );
    return ret;
  }

  Future<AfCoinCreateModel> coinCreateOrder({
    required String goodsCode,
  }) async {
    final ret = await AfHttpUtil.I.postParse(
      AfGlobalUrl.createOrderApi,
      params: {
        "entry": "",
        "source": "",
        "goodsCode": goodsCode,
        "payChannel": 'IAP'
      },
      parseJsonFn: ((data) => AfCoinCreateModel.fromJson(data)),
    );
    return ret;
  }

  Future<bool> payForGift({required int outlay}) async {
    await AfHttpUtil.I.postParse(
      AfGlobalUrl.payForGiftApi,
      params: {"outlay": outlay, "source": 'iap'},
      parseJsonFn: ((data) => data),
    );
    return true;
  }

  Future<bool> verifyPurchase({
    required String orderNo,
    required String payload,
    required String transactionId,
  }) async {
    await AfHttpUtil.I.postParse(
      AfGlobalUrl.verifyPurchaseApi,
      params: {
        "orderNo": orderNo,
        "payload": payload,
        "transactionId": transactionId,
        "type": "1"
      },
      parseJsonFn: ((data) => data),
    );
    return true;
  }

  Future<bool> addFriend({required String userId}) async {
    await AfHttpUtil.I.postParse(
      AfGlobalUrl.followApi,
      params: {"followUserId": userId},
      parseJsonFn: (data) => data,
    );

    return true;
  }

  Future<bool> unfriend({required String userId}) async {
    await AfHttpUtil.I.postParse(
      AfGlobalUrl.unfollowApi,
      params: {"followUserId": userId},
      parseJsonFn: (data) => data,
    );

    return true;
  }

  Future<AfFollowedListState> getFriendsList({
    int limit = 10,
    int page = 1,
  }) async {
    final ret =
        await AfHttpUtil.I.postParse(AfGlobalUrl.getFriendsList, params: {
      "limit": limit,
      "page": page,
    }, parseJsonFn: (data) {
      final list = List<AfFriendInfoModel>.from(
          data.map((x) => AfFriendInfoModel.fromJson(x)));
      return list;
    });

    return AfFollowedListState(
      currentPage: page + 1,
      refreshState: EasyRefreshState.refreshSuccess(hasMore: ret.isNotEmpty),
      dataList: ret,
    );
  }

  Future<bool> block({required String broadcasterId}) async {
    await AfHttpUtil.I.postParse(
      AfGlobalUrl.blockApi,
      params: {
        "broadcasterId": broadcasterId,
        "complainCategory": "Block",
        "complainSub": "",
      },
      parseJsonFn: (data) => data,
    );

    return true;
  }

  Future<bool> unblock({required String broadcasterId}) async {
    await AfHttpUtil.I.postParse(
      AfGlobalUrl.unblockApi,
      params: {
        "blockUserId": broadcasterId,
      },
      parseJsonFn: (data) => data,
    );

    return true;
  }

  Future<List<AfBlockListModel>> getBlockList() async {
    final ret = await AfHttpUtil.I.postParse(AfGlobalUrl.blockListApi,
        parseJsonFn: (data) {
      final list = List<AfBlockListModel>.from(
          data.map((x) => AfBlockListModel.fromJson(x)));
      return list;
    });

    return ret;
  }

  Future<bool> report(
      {required String userId, required String complainSub}) async {
    await AfHttpUtil.I.postParse(
      AfGlobalUrl.blockApi,
      params: {
        "broadcasterId": userId,
        "complainCategory": "Report",
        "complainSub": complainSub,
      },
      parseJsonFn: (data) => data,
    );

    return true;
  }

  Future<bool> deleteAccount() async {
    await AfHttpUtil.I.postParse(
      AfGlobalUrl.deleteAccountApi,
      params: {},
      parseJsonFn: (data) => data,
    );
    return true;
  }

  Future<bool> logout() async {
    await AfHttpUtil.I.postParse(
      AfGlobalUrl.logoutApi,
      params: {},
      parseJsonFn: (data) => data,
    );
    return true;
  }

  Future<AfOssPolicyModel> getOssModelFetchApiModel() async {
    final ret = await AfHttpUtil.I.getParse(
      AfGlobalUrl.ossModelFetchApi,
      params: {},
      parseJsonFn: (data) => AfOssPolicyModel.fromJson(data),
    );

    return ret;
  }

  Future<String> uploadPhoto({
    required File file,
    required AfOssPolicyModel userOssPolicyModel,
  }) async {
    DateTime dateTime = DateTime.now();
    String fileName = file.path.split(Platform.pathSeparator).last;
    String format = fileName.split('.').last;
    int imageTimeName = dateTime.millisecondsSinceEpoch +
        (dateTime.microsecondsSinceEpoch ~/ 1000000);
    var filePath = await MultipartFile.fromFile(file.path, filename: fileName);
    final formData = FormData.fromMap({
      'ossaccessKeyId': userOssPolicyModel.accessKeyId,
      'policy': userOssPolicyModel.policy,
      'signature': userOssPolicyModel.signature,
      'callback': userOssPolicyModel.callback,
      'key': '${userOssPolicyModel.dir!}${'$imageTimeName.$format'}',
      'file': filePath,
    });
    Dio dio = Dio();
    var response = await dio.post(userOssPolicyModel.host!, data: formData);

    if (response.data != null) {
      if (response.data["data"]["filename"] != null) {
        return response.data["data"]["filename"];
      } else {
        throw Exception("upload photo error");
      }
    } else {
      throw Exception("upload photo error");
    }
  }

  Future<String> updateAvatar({required String avatarPath}) async {
    final ret = await AfHttpUtil.I.postParse(
      AfGlobalUrl.updateUserAvatarApi,
      params: {"avatarPath": avatarPath},
      parseJsonFn: (data) => data['mediaUrl'],
    );

    return ret;
  }

  Future<bool> updateUserInfo({required Map<String, dynamic> params}) async {
    await AfHttpUtil.I.postParse(
      AfGlobalUrl.updateUserInfoApi,
      params: params,
      parseJsonFn: (data) => data,
    );
    return true;
  }
}

const videoParamStr = [
  {"mediaPath": "AeroFrisbee/video/1.mp4", "mediaType": "video"},
  {"mediaPath": "AeroFrisbee/video/2.mp4", "mediaType": "video"},
  {"mediaPath": "AeroFrisbee/video/3.mp4", "mediaType": "video"},
  {"mediaPath": "AeroFrisbee/video/4.mp4", "mediaType": "video"},
  {"mediaPath": "AeroFrisbee/video/5.mp4", "mediaType": "video"},
  {"mediaPath": "AeroFrisbee/video/6.mp4", "mediaType": "video"},
  {"mediaPath": "AeroFrisbee/video/7.mp4", "mediaType": "video"},
  {"mediaPath": "AeroFrisbee/video/8.mp4", "mediaType": "video"},
  {"mediaPath": "AeroFrisbee/video9.mp4", "mediaType": "video"},
  {"mediaPath": "AeroFrisbee/video/10.mp4", "mediaType": "video"},
  {"mediaPath": "AeroFrisbee/video/11.mp4", "mediaType": "video"},
  {"mediaPath": "AeroFrisbee/video/12.mp4", "mediaType": "video"}
];
